socket 编程

本文针对使用 TCP 协议的 socket 编程

服务端

创建 socket

int socket_fd = socket(AF_INET, SOCK_STREAM, 0);
if (socket_fd == -1) {
    panic("socket: %s\n", strerror(errno));
}

绑定服务器地址

int port = ...;
// 先创建 socket 地址结构体
struct sockaddr_in* socket_addr = malloc(sizeof(struct sockaddr_in));
socket_addr->sin_family = AF_INET; // IPv4
socket_addr->sin_port = htons(port); // set port
socket_addr->sin_addr.s_addr = htonl(INADDR_ANY); // accept any address 即绑定所有网卡

if (bindaddr) {
    // convert a address string, like "127.0.0.1",
    // into number form, like 0x7f000001,
    // and assign it to `socket_addr->sin_addr`
    // 绑定指定网卡
    int status_code = inet_pton(AF_INET, bindaddr, &socket_addr->sin_addr);
    if (status_code == 0) {
        close(socket_fd);
        panic("Invalid bind address\n");
    }
}

int status_code = bind(socket_fd, (struct sockaddr*)socket_addr, sizeof(struct sockaddr));
if (status_code == -1) {
    close(socket_fd);
    panic("socket bind: %s\n", strerror(errno));
}

监听 socket

int status_code = listen(socket_fd, 64);
if (status_code == -1) {
    close(socket_fd);
    panic("listen: %s\n", strerror(errno));
}

接收客户端连接

struct sockaddr_in socket_addr;
socklen_t socket_addr_len = sizeof(socket_addr);
int client_fd = accept(server_fd, (struct sockaddr*)&socket_addr, &socket_addr_len);

接收之后可以使用 read / recv 或者 write / send 进行数据传输。

客户端

创建 socket

int socket_fd = socket(AF_INET, SOCK_STREAM, 0);
if (socket_fd == -1) {
    panic("socket: %s\n", strerror(errno));
}

创建服务器地址结构体

char* addr = "127.0.0.1"; // 服务器 IP 地址 或 服务器域名
int port = ...; // 服务器端口

struct sockaddr_in* socket_addr = malloc(sizeof(struct sockaddr_in));
memset(socket_addr, 0, sizeof(socket_addr));
socket_addr->sin_family = AF_INET; // IPv4
socket_addr->sin_port = htons(port); // set port

int status_code = inet_aton(addr, &socket_addr->sin_addr);
if (status_code != 0) {
    return socket_addr;
}

// addr is invalid, maybe a hostname like `localhost`
struct hostent* he;
he = gethostbyname(addr);

if (he == NULL) {
    panic("can't resolve: %s\n", addr);
}
memcpy(&socket_addr->sin_addr, he->h_addr, sizeof(struct in_addr));
return socket_addr;

发起连接

int status_code = connect(socket_fd, (struct sockaddr*)socket_addr, sizeof(struct sockaddr));
if (status_code == -1 && errno != EINPROGRESS) {
    close(socket_fd);
    panic("connect: %s\n", strerror(errno));
}

连接之后可以使用 read / recv 或者 write / send 进行数据传输

点此查看原文